cmake_minimum_required ( VERSION 3.10 FATAL_ERROR )

project( SimpleITK_CSharp )

include(../../CMake/sitkProjectLanguageCommon.cmake NO_POLICY_SCOPE)


# Find C#
find_package( CSharp REQUIRED )
include( ${CSHARP_USE_FILE} )

include_directories( ${SimpleITK_INCLUDE_DIRS} )

set_source_files_properties ( SimpleITK.i PROPERTIES CPLUSPLUS ON )

# CSharp version requirements: http://msdn.microsoft.com/en-us/library/system.reflection.assemblyversionattribute.aspx
# major.minor[.build[.revision]] where all components are 16-bit unsigned integers
set(_build 0)
if(DEFINED SimpleITK_VERSION_POST AND NOT "${SimpleITK_VERSION_POST}" STREQUAL "")
  math(EXPR _build "${SimpleITK_VERSION_POST}")
elseif(DEFINED SimpleITK_VERSION_DEV AND NOT "${SimpleITK_VERSION_DEV}" STREQUAL "")
  math(EXPR _build "32768+${SimpleITK_VERSION_DEV}")
endif()
if(_build GREATER 65535)
  message(WARNING "CSharp build component overflowed, setting to 65535 instead of ${_build}.")
  set(_build 65535)
endif()

set(_revision 0)
if(DEFINED SimpleITK_VERSION_PATCH)
  math(EXPR _revision "${SimpleITK_VERSION_PATCH}<<8")
  if(DEFINED SimpleITK_VERSION_TWEAK)
    math(EXPR _revision "${_revision}+${SimpleITK_VERSION_TWEAK}")
  endif()
endif()
if(_revision GREATER 65535)
  message(WARNING "CSharp revision component overflowed, setting to 65535 instead of ${_revision}.")
  set(_revision 65535)
endif()

  set(SimpleITK_VERSION_CSHARP_AssemblyVersion "${SimpleITK_VERSION_MAJOR}.${SimpleITK_VERSION_MINOR}.${_build}.${_revision}")

  # Make sure the nested directory structure exists
  set(CSHARP_SOURCE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/CSharpSources CACHE INTERNAL "")
  set(CSHARP_BINARY_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/CSharpBinaries CACHE INTERNAL "")
  file(MAKE_DIRECTORY ${CSHARP_SOURCE_DIRECTORY})
  file(MAKE_DIRECTORY ${CSHARP_BINARY_DIRECTORY})

  # Create swig target
  set(CMAKE_SWIG_OUTDIR ${CSHARP_SOURCE_DIRECTORY})
  if ( UNIX )
    set(CMAKE_SWIG_FLAGS -dllimport \"libSimpleITKCSharpNative\")
  else (WIN32 )
    set(CMAKE_SWIG_FLAGS -dllimport \"SimpleITKCSharpNative\")
  endif ( UNIX )
  set(CMAKE_SWIG_FLAGS -I${CMAKE_CURRENT_SOURCE_DIR} -namespace \"itk.simple\" ${CMAKE_SWIG_GLOBAL_FLAGS} ${CMAKE_SWIG_FLAGS})
  set(SWIG_MODULE_SimpleITKCSharpNative_EXTRA_DEPS ${SWIG_EXTRA_DEPS}
    ${CMAKE_CURRENT_SOURCE_DIR}/CSharp.i
    ${CMAKE_CURRENT_SOURCE_DIR}/CSharpTypemapHelper.i )
  swig_add_module(SimpleITKCSharpNative csharp SimpleITK.i)
  target_link_libraries(${SWIG_MODULE_SimpleITKCSharpNative_TARGET_NAME} ${SimpleITK_LIBRARIES})
  set_target_properties(${SWIG_MODULE_SimpleITKCSharpNative_TARGET_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CSHARP_BINARY_DIRECTORY})
  if ( UNIX )
    set_target_properties(${SWIG_MODULE_SimpleITKCSharpNative_TARGET_NAME} PROPERTIES PREFIX "lib")
    set_target_properties(${SWIG_MODULE_SimpleITKCSharpNative_TARGET_NAME} PROPERTIES SUFFIX ".so")
  else ( WIN32 )
    set_target_properties(${SWIG_MODULE_SimpleITKCSharpNative_TARGET_NAME} PROPERTIES PREFIX "")
    set_target_properties(${SWIG_MODULE_SimpleITKCSharpNative_TARGET_NAME} PROPERTIES SUFFIX ".dll")
    foreach ( CMAKE_CONFIGURATION_TYPE ${CMAKE_CONFIGURATION_TYPES} )
      string(TOUPPER ${CMAKE_CONFIGURATION_TYPE} CMAKE_CONFIGURATION_TYPE)
      set_target_properties(${SWIG_MODULE_SimpleITKCSharpNative_TARGET_NAME}
        PROPERTIES LIBRARY_OUTPUT_DIRECTORY_${CMAKE_CONFIGURATION_TYPE} "${CSHARP_BINARY_DIRECTORY}")
      set_target_properties(${SWIG_MODULE_SimpleITKCSharpNative_TARGET_NAME}
        PROPERTIES RUNTIME_OUTPUT_DIRECTORY_${CMAKE_CONFIGURATION_TYPE} "${CSHARP_BINARY_DIRECTORY}")
    endforeach( )
  endif( UNIX )
  sitk_strip_target( ${SWIG_MODULE_SimpleITKCSharpNative_TARGET_NAME} )

  # These CSharp files are generated by SWIG, they are not there
  # during the first build. But the charp_add_library will add them as
  # a dependency when the exists. This is needed for CMP0058
  file(GLOB _files "${CSHARP_SOURCE_DIRECTORY}/*.cs")
  add_custom_command( TARGET ${SWIG_MODULE_SimpleITKCSharpNative_TARGET_NAME}
    POST_BUILD
    BYPRODUCTS ${_files} )

  # Configure AssemblyInfo.cs
  configure_file(
    ${CMAKE_CURRENT_SOURCE_DIR}/AssemblyInfo.cs.in
    ${CSHARP_SOURCE_DIRECTORY}/AssemblyInfo.cs
    @ONLY
  )

  # Add managed wrapper
  csharp_add_library(
    SimpleITKCSharpManaged
    ${CSHARP_SOURCE_DIRECTORY}/*.cs
  )
  add_dependencies(SimpleITKCSharpManaged ${SWIG_MODULE_SimpleITKCSharpNative_TARGET_NAME})


# Packaging for distribution
add_subdirectory(dist)
